import 'package:flutter/widgets.dart';

import 'change_notifier_provider.dart';

class Selector<A, T> extends StatefulWidget {
  const Selector({
    Key key,
    @required this.builder,
    @required this.selector,
    this.child,
  })  : assert(builder != null),
        assert(selector != null),
        super(key: key);
  final Widget child;

  final Widget Function(BuildContext context, T value, Widget child) builder;

  final T Function(BuildContext context, A vm) selector;

  @override
  _SelectorState<A, T> createState() => _SelectorState<A, T>();
}

class _SelectorState<A, T> extends State<Selector<A, T>> {
  T value;
  Widget cache;
  Widget oldWidget;

  @override
  Widget build(BuildContext context) {
    final T selected = widget.selector(
        context,
        ChangeNotifierProvider.of<A>(
          context,
        ));

    final bool shouldInvalidateCache = oldWidget != widget || selected != value;

    if (shouldInvalidateCache) {
      value = selected;
      oldWidget = widget;
      cache = widget.builder(
        context,
        selected,
        widget.child,
      );
    }
    return cache;
  }
}
